<?php

namespace app\admin\controller\scanwork;

use app\common\controller\Backend;
use app\admin\model\scanwork\TraceCode as TraceCodeModel;
use app\admin\model\scanwork\Config as ConfigModel;
use think\Db;

/**
 * 主动报工追溯码管理
 */
class ActiveTraceCode extends Backend
{
    protected $model = null;
    protected $noNeedRight = ['index', 'getTraceInfo', 'downloadQrCode', 'generate', 'generateAll', 'preview', 'detail'];
    protected $dataLimit = false; // 关闭数据权限限制

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new TraceCodeModel;
    }

    /**
     * 查看
     */
    public function index()
    {
        if ($this->request->isAjax()) {
            // 直接查询，不使用buildparams
            $list = $this->model
                ->alias('t')
                ->join('fa_scanwork_active_report ar', 't.active_report_id = ar.id')
                ->join('fa_scanwork_order o', 'ar.order_id = o.id', 'LEFT')
                ->join('fa_scanwork_model m', 'ar.model_id = m.id', 'LEFT')
                ->join('fa_scanwork_process p', 'ar.process_id = p.id', 'LEFT')
                ->join('fa_user worker', 'ar.user_id = worker.id', 'LEFT')
                ->join('fa_user auditor', 'ar.audit_user_id = auditor.id', 'LEFT')
                ->field('t.*, o.order_no, m.name as model_name, m.model_code, p.name as process_name, worker.nickname as worker_name, auditor.nickname as auditor_name, ar.quantity, ar.work_hours, ar.total_wage, ar.remark, ar.audit_time as report_audit_time, ar.audit_reason')
                ->where('t.active_report_id', 'neq', null)
                ->order('t.id', 'desc')
                ->paginate(10);

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result, JSON_UNESCAPED_UNICODE);
        }
        return $this->view->fetch();
    }

    /**
     * 删除
     */
    public function del($ids = "")
    {
        if (!$this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ? $ids : $this->request->post("ids");
        if ($ids) {
            $pk = $this->model->getPk();
            $adminIds = $this->getDataLimitAdminIds();
            if (is_array($adminIds)) {
                $this->model->where($this->dataLimitField, 'in', $adminIds);
            }
            $list = $this->model->where($pk, 'in', $ids)->where('active_report_id', 'neq', null)->select();

            $count = 0;
            Db::startTrans();
            try {
                foreach ($list as $item) {
                    $count += $item->delete();
                }
                Db::commit();
            } catch (\think\exception\PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (\think\Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($count) {
                $this->success();
            } else {
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }

    /**
     * 下载二维码
     */
    public function downloadQrCode($ids = null)
    {
        if (!$ids) {
            $this->error('请选择要下载的追溯码');
        }

        $traceIds = explode(',', $ids);
        $traceCodes = $this->model->where('id', 'in', $traceIds)->where('active_report_id', 'neq', null)->select();

        if (empty($traceCodes)) {
            $this->error('未找到主动报工追溯码记录');
        }

        // 生成二维码并打包下载
        $zipFile = $this->generateQrCodeZip($traceCodes);
        
        if ($zipFile && file_exists($zipFile)) {
            header('Content-Type: application/zip');
            header('Content-Disposition: attachment; filename="active_trace_codes_' . date('YmdHis') . '.zip"');
            header('Content-Length: ' . filesize($zipFile));
            readfile($zipFile);
            unlink($zipFile); // 删除临时文件
            exit;
        } else {
            $this->error('生成二维码文件失败');
        }
    }

    /**
     * 生成二维码ZIP包
     */
    private function generateQrCodeZip($traceCodes)
    {
        $tempDir = ROOT_PATH . 'public' . DS . 'temp' . DS . 'qrcodes' . DS;
        if (!is_dir($tempDir)) {
            mkdir($tempDir, 0755, true);
        }

        $zipFile = $tempDir . 'active_trace_codes_' . time() . '.zip';
        $zip = new \ZipArchive();
        
        if ($zip->open($zipFile, \ZipArchive::CREATE) !== TRUE) {
            return false;
        }

        foreach ($traceCodes as $trace) {
            // 生成二维码内容（追溯页面URL）
            $traceUrl = ConfigModel::getSiteDomain() . '/trace.html?id=' . $trace->trace_code;
            
            // 获取追溯码详细信息（包含关联数据）
            $traceData = $this->getTraceDetailData($trace->id);
            
            // 生成二维码图片
            $qrCodeFile = $this->generateQrCodeImage($traceUrl, $trace->trace_code, $traceData);
            
            if ($qrCodeFile) {
                // 生成包含产品名称和员工姓名的文件名
                $fileName = $this->generateFileName($traceData);
                $zip->addFile($qrCodeFile, $fileName . '.png');
            }
        }

        $zip->close();
        return $zipFile;
    }

    /**
     * 生成二维码图片
     */
    private function generateQrCodeImage($content, $filename, $traceData = null)
    {
        $qrCodeDir = ROOT_PATH . 'public' . DS . 'temp' . DS . 'qrcodes' . DS;
        if (!is_dir($qrCodeDir)) {
            mkdir($qrCodeDir, 0755, true);
        }
        
        $qrCodeFile = $qrCodeDir . $filename . '.png';
        
        // 使用在线API生成二维码
        $apiUrl = 'https://api.qrserver.com/v1/create-qr-code/';
        $params = [
            'size' => '300x300',
            'data' => $content,
            'format' => 'png'
        ];
        
        $url = $apiUrl . '?' . http_build_query($params);
        
        // 下载二维码图片
        $qrCodeImage = file_get_contents($url);
        
        if ($qrCodeImage !== false) {
            file_put_contents($qrCodeFile, $qrCodeImage);
            return $qrCodeFile;
        }
        
        // 如果在线API失败，创建一个简单的占位符图片
        $this->createPlaceholderQrCode($qrCodeFile, $content, $traceData);
        return $qrCodeFile;
    }

    /**
     * 创建占位符二维码图片
     */
    private function createPlaceholderQrCode($filepath, $content, $traceData = null)
    {
        // 创建一个更大的图片来容纳更多信息
        $width = 400;
        $height = 500;
        
        // 创建图片
        $image = imagecreate($width, $height);
        
        // 设置颜色
        $white = imagecolorallocate($image, 255, 255, 255);
        $black = imagecolorallocate($image, 0, 0, 0);
        $gray = imagecolorallocate($image, 128, 128, 128);
        $blue = imagecolorallocate($image, 0, 123, 255);
        $green = imagecolorallocate($image, 40, 167, 69);
        
        // 填充白色背景
        imagefill($image, 0, 0, $white);
        
        // 绘制边框
        imagerectangle($image, 0, 0, $width-1, $height-1, $black);
        
        // 绘制标题
        $title = "主动报工追溯码";
        $fontSize = 5;
        $titleWidth = imagefontwidth($fontSize) * strlen($title);
        $titleX = ($width - $titleWidth) / 2;
        $titleY = 20;
        imagestring($image, $fontSize, $titleX, $titleY, $title, $blue);
        
        // 绘制追溯码
        if ($traceData && isset($traceData['trace_code'])) {
            $traceCode = "追溯码: " . $traceData['trace_code'];
            $traceWidth = imagefontwidth($fontSize) * strlen($traceCode);
            $traceX = ($width - $traceWidth) / 2;
            $traceY = $titleY + 30;
            imagestring($image, $fontSize, $traceX, $traceY, $traceCode, $black);
        }
        
        // 绘制产品信息
        $y = $traceY + 30;
        if ($traceData) {
            $infoLines = [];
            
            if (isset($traceData['product_name']) && $traceData['product_name']) {
                $infoLines[] = "产品: " . $traceData['product_name'];
            }
            
            if (isset($traceData['model_name']) && $traceData['model_name']) {
                $infoLines[] = "型号: " . $traceData['model_name'];
            }
            
            if (isset($traceData['process_name']) && $traceData['process_name']) {
                $infoLines[] = "工序: " . $traceData['process_name'];
            }
            
            if (isset($traceData['worker_name']) && $traceData['worker_name']) {
                $infoLines[] = "员工: " . $traceData['worker_name'];
            }
            
            if (isset($traceData['audit_time']) && $traceData['audit_time']) {
                $auditTime = date('Y-m-d H:i', $traceData['audit_time']);
                $infoLines[] = "时间: " . $auditTime;
            }
            
            // 绘制信息行
            foreach ($infoLines as $line) {
                $lineWidth = imagefontwidth($fontSize) * strlen($line);
                $lineX = ($width - $lineWidth) / 2;
                imagestring($image, $fontSize, $lineX, $y, $line, $gray);
                $y += 20;
            }
        }
        
        // 绘制二维码说明
        $y += 20;
        $note = "扫描二维码查看详细信息";
        $noteWidth = imagefontwidth($fontSize) * strlen($note);
        $noteX = ($width - $noteWidth) / 2;
        imagestring($image, $fontSize, $noteX, $y, $note, $green);
        
        // 绘制URL（截取显示）
        $y += 20;
        $displayUrl = "URL: " . substr($content, 0, 35) . "...";
        $urlWidth = imagefontwidth($fontSize) * strlen($displayUrl);
        $urlX = ($width - $urlWidth) / 2;
        imagestring($image, $fontSize, $urlX, $y, $displayUrl, $gray);
        
        // 保存图片
        imagepng($image, $filepath);
        imagedestroy($image);
    }

    /**
     * 获取追溯码详细信息
     */
    private function getTraceDetailData($traceId)
    {
        $trace = Db::name('scanwork_trace_codes')
            ->alias('t')
            ->join('fa_scanwork_active_report ar', 't.active_report_id = ar.id')
            ->join('fa_scanwork_order o', 'ar.order_id = o.id')
            ->join('fa_scanwork_model m', 'ar.model_id = m.id')
            ->join('fa_scanwork_product p', 'm.product_id = p.id')
            ->join('fa_scanwork_process proc', 'ar.process_id = proc.id')
            ->join('fa_user worker', 'ar.user_id = worker.id')
            ->join('fa_user auditor', 'ar.audit_user_id = auditor.id', 'LEFT')
            ->field('t.*, o.order_no, o.customer_name, m.name as model_name, m.model_code, p.name as product_name, proc.name as process_name, worker.nickname as worker_name, auditor.nickname as auditor_name, ar.quantity, ar.work_hours, ar.total_wage, ar.remark as report_remark, ar.audit_time as report_audit_time, ar.audit_reason')
            ->where('t.id', $traceId)
            ->find();

        return $trace ? $trace : [];
    }

    /**
     * 生成包含产品信息的文件名
     */
    private function generateFileName($traceData)
    {
        $parts = [];
        
        // 添加追溯码
        $parts[] = $traceData['trace_code'] ?? '';
        
        // 添加产品名称
        if (!empty($traceData['product_name'])) {
            $parts[] = $traceData['product_name'];
        }
        
        // 添加型号
        if (!empty($traceData['model_name'])) {
            $parts[] = $traceData['model_name'];
        }
        
        // 添加工序
        if (!empty($traceData['process_name'])) {
            $parts[] = $traceData['process_name'];
        }
        
        // 添加员工姓名
        if (!empty($traceData['worker_name'])) {
            $parts[] = $traceData['worker_name'];
        }
        
        // 添加审核时间（年月日）
        if (!empty($traceData['report_audit_time'])) {
            $parts[] = date('Ymd', $traceData['report_audit_time']);
        }
        
        // 组合文件名，用下划线分隔
        $fileName = implode('_', array_filter($parts));
        
        // 移除特殊字符，只保留字母、数字、中文和下划线
        $fileName = preg_replace('/[^a-zA-Z0-9\x{4e00}-\x{9fa5}_]/u', '', $fileName);
        
        return $fileName;
    }

    /**
     * 预览追溯页面
     */
    public function preview($id = null)
    {
        $trace = $this->model->where('id', $id)->where('active_report_id', 'neq', null)->find();
        if (!$trace) {
            $this->error('追溯码不存在');
        }

        $traceUrl = ConfigModel::getSiteDomain() . '/trace.html?id=' . $trace->trace_code;
        $this->redirect($traceUrl);
    }

    /**
     * 查看主动报工详情
     */
    public function detail($id = null)
    {
        // 支持通过追溯码或ID查询
        if (is_numeric($id)) {
            $where = 't.id = ' . intval($id);
        } else {
            $where = "t.trace_code = '" . addslashes($id) . "'";
        }

        $trace = $this->model
            ->alias('t')
            ->join('fa_scanwork_active_report ar', 't.active_report_id = ar.id')
            ->join('fa_scanwork_order o', 'ar.order_id = o.id')
            ->join('fa_scanwork_model m', 'ar.model_id = m.id')
            ->join('fa_scanwork_process p', 'ar.process_id = p.id')
            ->join('fa_user worker', 'ar.user_id = worker.id', 'LEFT')
            ->join('fa_user auditor', 'ar.audit_user_id = auditor.id', 'LEFT')
            ->field('t.*, o.order_no, o.customer_name, m.name as model_name, m.model_code, p.name as process_name, worker.nickname as worker_name, auditor.nickname as auditor_name, ar.quantity, ar.work_hours, ar.total_wage, ar.remark, ar.audit_time as report_audit_time, ar.audit_reason')
            ->where($where)
            ->where('t.active_report_id', 'neq', null)
            ->find();

        if (!$trace) {
            $this->error('追溯码不存在或已失效');
        }

        // 转换为数组
        $trace = $trace->toArray();

        // 处理产品编号，解析JSON数组
        if ($trace && isset($trace['item_no']) && $trace['item_no']) {
            $itemNos = json_decode($trace['item_no'], true);
            if (is_array($itemNos)) {
                $trace['item_nos_array'] = $itemNos;
            } else {
                $trace['item_nos_array'] = [$trace['item_no']];
            }
        } else {
            $trace['item_nos_array'] = [];
        }

        // 获取主动报工的产品编号图片
        $activeReportItems = Db::name('scanwork_active_report_product_item')
            ->where('active_report_id', $trace['active_report_id'])
            ->field('item_no, image_url, createtime')
            ->select();
        
        // 按item_no分组
        $itemGroups = [];
        foreach ($activeReportItems as $item) {
            $itemNo = $item['item_no'];
            if (!isset($itemGroups[$itemNo])) {
                $itemGroups[$itemNo] = [
                    'item_no' => $itemNo,
                    'audit_images' => [],
                    'audit_videos' => []
                ];
            }
            
            // 根据文件扩展名分类图片和视频
            $extension = strtolower(pathinfo($item['image_url'], PATHINFO_EXTENSION));
            if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'])) {
                $itemGroups[$itemNo]['audit_images'][] = [
                    'image_url' => $item['image_url'],
                    'createtime' => $item['createtime']
                ];
            } elseif (in_array($extension, ['mp4', 'avi', 'mov', 'wmv', 'flv'])) {
                $itemGroups[$itemNo]['audit_videos'][] = [
                    'image_url' => $item['image_url'],
                    'createtime' => $item['createtime']
                ];
            }
        }
        
        $trace['item_media'] = array_values($itemGroups);

        // 获取主动报工图片（不按产品编号分组）
        $trace['report_images'] = Db::name('scanwork_active_report_image')
            ->where('active_report_id', $trace['active_report_id'])
            ->where('image_type', 1) // 员工上传的图片
            ->field('image_url, createtime')
            ->select();

        $this->view->assign('trace', $trace);
        return $this->view->fetch();
    }

    /**
     * 获取追溯信息（用于前端页面）
     */
    public function getTraceInfo()
    {
        $traceCode = $this->request->get('id');
        
        if (!$traceCode) {
            return json(['code' => 0, 'msg' => '缺少追溯码参数']);
        }
        
        // 支持通过追溯码或ID查询
        if (is_numeric($traceCode)) {
            $where = 't.id = ' . intval($traceCode);
        } else {
            $where = "t.trace_code = '" . addslashes($traceCode) . "'";
        }

        $trace = $this->model
            ->alias('t')
            ->join('fa_scanwork_active_report ar', 't.active_report_id = ar.id')
            ->join('fa_scanwork_order o', 'ar.order_id = o.id')
            ->join('fa_scanwork_model m', 'ar.model_id = m.id')
            ->join('fa_scanwork_process p', 'ar.process_id = p.id')
            ->join('fa_user worker', 'ar.user_id = worker.id', 'LEFT')
            ->join('fa_user auditor', 'ar.audit_user_id = auditor.id', 'LEFT')
            ->field('t.*, o.order_no, o.customer_name, m.name as model_name, m.model_code, p.name as process_name, worker.nickname as worker_name, auditor.nickname as auditor_name, ar.quantity, ar.work_hours, ar.total_wage, ar.remark, ar.audit_time as report_audit_time, ar.audit_reason')
            ->where($where)
            ->where('t.active_report_id', 'neq', null)
            ->find();

        if (!$trace) {
            return json(['code' => 0, 'msg' => '追溯码不存在或已失效']);
        }

        // 转换为数组
        $trace = $trace->toArray();

        // 处理产品编号，解析JSON数组
        if ($trace && isset($trace['item_no']) && $trace['item_no']) {
            $itemNos = json_decode($trace['item_no'], true);
            if (is_array($itemNos)) {
                $trace['item_nos_array'] = $itemNos;
            } else {
                $trace['item_nos_array'] = [$trace['item_no']];
            }
        } else {
            $trace['item_nos_array'] = [];
        }

        // 获取主动报工的产品编号图片
        $activeReportItems = Db::name('scanwork_active_report_product_item')
            ->where('active_report_id', $trace['active_report_id'])
            ->field('item_no, image_url, createtime')
            ->select();
        
        // 按item_no分组
        $itemGroups = [];
        foreach ($activeReportItems as $item) {
            $itemNo = $item['item_no'];
            if (!isset($itemGroups[$itemNo])) {
                $itemGroups[$itemNo] = [
                    'item_no' => $itemNo,
                    'audit_images' => [],
                    'audit_videos' => []
                ];
            }
            
            // 根据文件扩展名分类图片和视频
            $extension = strtolower(pathinfo($item['image_url'], PATHINFO_EXTENSION));
            if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'])) {
                $itemGroups[$itemNo]['audit_images'][] = [
                    'image_url' => $item['image_url'],
                    'createtime' => $item['createtime']
                ];
            } elseif (in_array($extension, ['mp4', 'avi', 'mov', 'wmv', 'flv'])) {
                $itemGroups[$itemNo]['audit_videos'][] = [
                    'image_url' => $item['image_url'],
                    'createtime' => $item['createtime']
                ];
            }
        }
        
        $trace['item_media'] = array_values($itemGroups);

        // 获取主动报工图片（不按产品编号分组）
        $trace['report_images'] = Db::name('scanwork_active_report_image')
            ->where('active_report_id', $trace['active_report_id'])
            ->where('image_type', 1) // 员工上传的图片
            ->field('image_url, createtime')
            ->select();
        
        return json(['code' => 1, 'msg' => '获取成功', 'data' => $trace]);
    }
}
